﻿ 
using Microsoft.AspNetCore.Builder;
using Microsoft.Data.SqlClient; 
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Serilog;
using Serilog.Core;
using Serilog.Enrichers.CallerInfo;
using Serilog.Events;
using Serilog.Formatting.Display;
using Serilog.Sinks.Email;
using Serilog.Sinks.MSSqlServer;
using Serilog.Sinks.SystemConsole.Themes;
using SSPivot.Common.Helpers;
using SSPivot.Common.Serilog;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class SerilogExtensions
    {
        public static Logger CreateSerilogLogger(IConfiguration configuration)
        {

            #region C#
            var config = configuration.GetSection("Serilog").Get<SerilogConfig>();  

            var logConfig = new LoggerConfiguration()
               .MinimumLevel.Information()
               .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
               .Enrich.WithCallerInfo(includeFileInfo: true, assemblyPrefix: "SSPivot.")
               .Enrich.FromLogContext()
               //.Enrich.WithMachineName()
               //.Enrich.WithProcessId()
               //.Enrich.WithThreadId()
               .WriteTo.Console()
               .WriteTo.File(
                   path: "Logs/log-.txt",
                   rollingInterval: RollingInterval.Day,
                   outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {TraceIdentifier} {IP} {Message}{NewLine}{Exception}"
               );
            if (config.IsSqlServerEnabled)
            {

                var sinkOpts = new MSSqlServerSinkOptions();
                sinkOpts.TableName = "serilog_logs";
                sinkOpts.AutoCreateSqlTable = true;
                sinkOpts.BatchPostingLimit = 1;
                sinkOpts.BatchPeriod = TimeSpan.FromSeconds(1);
                var sqlColumnOptions = new ColumnOptions();
                sqlColumnOptions.Store.Remove(StandardColumn.Properties);
                sqlColumnOptions.Store.Add(StandardColumn.LogEvent);
                sqlColumnOptions.AdditionalColumns = new List<SqlColumn>
            {
                new SqlColumn { DataType = SqlDbType.NVarChar, ColumnName = "IP", DataLength = 45 },
                new SqlColumn { DataType = SqlDbType.NVarChar, ColumnName = "TraceIdentifier", DataLength = 100 }
            };
                logConfig = logConfig.WriteTo.MSSqlServer(
                    connectionString: config.ConnString, 
                    sinkOptions: sinkOpts,
                    columnOptions: sqlColumnOptions,
                    restrictedToMinimumLevel: LogEventLevel.Information
                );
            }
            if (config.IsSeqEnabled)
            {
                logConfig = logConfig.WriteTo.Seq(config.SeqServerUrl, apiKey: config.SeqAppKey);
            }
            if (config.IsEmailEnabled)
            {
                var emailConfig = configuration.GetSection("Email").Get<MailConfig>(); 
                if (emailConfig != null &&
                    emailConfig.Host.IsNotNullOrWhiteSpace() &&
                    emailConfig.Port.HasValue &&
                    emailConfig.From.IsNotNullOrWhiteSpace() &&
                    emailConfig.FromName.IsNotNullOrWhiteSpace() &&
                    emailConfig.Password.IsNotNullOrWhiteSpace())
                {
                    logConfig = logConfig.WriteTo.Email(options: new EmailSinkOptions()
                    {
                        Host = emailConfig.Host,
                        Port = emailConfig.Port.Value,
                        From = emailConfig.From,
                        To = [emailConfig.From],
                        Credentials = new NetworkCredential(emailConfig.From, emailConfig.Password),
                        IsBodyHtml = false,
                        Subject = new MessageTemplateTextFormatter("系统错误，请速速查看"),
                        Body = new MessageTemplateTextFormatter("{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {TraceIdentifier} {IP} {Message}{NewLine}{Exception}")
                    },
                batchingOptions: null,
                restrictedToMinimumLevel: LogEventLevel.Error,
                levelSwitch: new LoggingLevelSwitch()
                {
                    MinimumLevel = LogEventLevel.Error
                });
                } 
            }

            return logConfig.CreateLogger();

            #endregion
            #region settings
            //Log.Logger = new LoggerConfiguration()
            //    .ReadFrom.Configuration(builder.Configuration)
            //    .Enrich.With<IPEnricher>()
            //    .Enrich.With<TraceIdentifierEnricher>()
            //    .CreateLogger();
            #endregion

    
        }
        public static void UseSSPivotSerilog(this WebApplication app)
        { 
            app.UseSerilogRequestLogging(options =>
            {
                options.EnrichDiagnosticContext = (diagnosticContext, httpContext) =>
                {
                    diagnosticContext.Set("TraceIdentifier", httpContext.TraceIdentifier);
                    diagnosticContext.Set("IP", httpContext.Connection.RemoteIpAddress?.ToString());
                };
            });
            app.UseMiddleware<LogEnricherMiddleware>();
        }
    } 
}
